package com.zengjianjun.es.demo.service.impl;

import com.alibaba.fastjson2.JSON;
import com.zengjianjun.es.demo.entity.EsActiveEntity;
import com.zengjianjun.es.demo.mapper.EsActiveMapper;
import com.zengjianjun.es.demo.param.EsActiveParam;
import com.zengjianjun.es.demo.service.EsActiveService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.data.elasticsearch.core.AggregationsContainer;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author zengjianjun
 */
@Slf4j
@Service
public class EsActiveServiceImpl implements EsActiveService {

    @Resource
    private EsActiveMapper esActiveMapper;
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;


    @Override
    public void save(EsActiveEntity entity) {
        this.esActiveMapper.save(entity);
    }

    @Override
    public void saveAll(List<EsActiveEntity> entityList) {
        this.esActiveMapper.saveAll(entityList);
    }

    @Override
    public void aggregation(EsActiveParam param, String offerEventsEs) {
        // 构建分组聚合
        TermsAggregationBuilder aggregation = AggregationBuilders
                .terms("publisherIdAggs")
                .field("publisherId")
                .size(20)
                .subAggregation(
                        AggregationBuilders
                                .terms("subAffIdAggs")
                                .field("subAffId")
                                .size(5)
                                .subAggregation(
                                        AggregationBuilders
                                                .filter("eventFilter", QueryBuilders.termQuery("event", StringUtils.isBlank(offerEventsEs) ? new Object[]{""} : offerEventsEs.split(",")))
                                                .subAggregation(
                                                        AggregationBuilders
                                                                .terms("eventAnyAggs")
                                                                .field("event")
                                                )
                                )
                                .subAggregation(
                                        AggregationBuilders.filter("eventFilterInstall", QueryBuilders.termQuery("event", "install"))
                                )
                                .subAggregation(
                                        AggregationBuilders.filter("eventFilterReattribution", QueryBuilders.termQuery("event", "reattribution"))
                                )
                );
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(this.getQueryBuilder(param))
                .withAggregations(aggregation)
//                .withPageable(PageRequest.of(0, 1))
                .withMaxResults(0)
                .build();

        // 执行查询并返回结果
        SearchHits<EsActiveEntity> search = elasticsearchRestTemplate.search(searchQuery, EsActiveEntity.class);
        AggregationsContainer<?> aggregations = search.getAggregations();
        log.info("{}", aggregations != null ? JSON.toJSONString(aggregations.aggregations()) : null);
    }

    private QueryBuilder getQueryBuilder(EsActiveParam param) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (param.getClickId() != null) {
            queryBuilder.must(QueryBuilders.prefixQuery("clickId", param.getClickId()));
        }
        if (param.getOfferId() != null) {
            queryBuilder.must(QueryBuilders.termQuery("offerId", param.getOfferId()));
        }
        if (param.getPublisherId() != null) {
            queryBuilder.must(QueryBuilders.termQuery("publisherId", param.getPublisherId()));
        }
        if (param.getSubAffId() != null) {
            queryBuilder.must(QueryBuilders.termQuery("subAffId", param.getSubAffId()));
        }
        if (param.getEvent() != null) {
            queryBuilder.must(QueryBuilders.termQuery("event", param.getEvent()));
        }
        return queryBuilder;
    }

    private Criteria getCriteria(EsActiveParam param) {
        Criteria criteria = new Criteria();
        if (param.getClickId() != null) {
            criteria.and(Criteria.where("clickId").startsWith(param.getClickId()));
        }
        if (param.getOfferId() != null) {
            criteria.and(Criteria.where("offerId").is(param.getOfferId()));
        }
        if (param.getPublisherId() != null) {
            criteria.and(Criteria.where("publisherId").is(param.getPublisherId()));
        }
        if (param.getSubAffId() != null) {
            criteria.and(Criteria.where("subAffId").is(param.getSubAffId()));
        }
        if (param.getEvent() != null) {
            criteria.and(Criteria.where("event").is(param.getEvent()));
        }
        return criteria;
    }
}
